package grex.Nodes.Depricated;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */
import grex.BNFException;
import grex.ErrorManagement.ErrorManager;
import grex.Options;
import grex.Data.Prediction;
import grex.Data.PredictionContainer;
import grex.Nodes.GeneException;
import grex.Nodes.ITerminal;
import grex.Nodes.Node;

import java.text.NumberFormat;

public class ProbTargetPred2 extends Node implements ITerminal {

    private static final int NROFCILDREN = 0;
    private double value = -1;
    private Double prob = new Double(0);
    private Double lowerProb = new Double(-1);
    private int count = 0;
    private double[] support = null;
    private int majority = -1,   length = 0;
    private double[] probs = null;
    private int[] probOrder = null;
    private int nrOfClasses = 0;
    private double totalSupport = 0;

    public ProbTargetPred2() throws BNFException {
        super(NROFCILDREN);

    }

    public synchronized void execute(Node parent, PredictionContainer data, int mode) throws GeneException {
        try {
            this.parent = parent;
            if (mode == Node.TRAIN_MODE || mode == Node.OPTIMIZE_MODE) {
                prob = new Double(0);
                lowerProb = new Double(0);
                count = data.values().size();
                double max = 0;
                if (ops.getPROBLEM_TYPE() == Options.CLASSIFICATION) {                    
                    if (support==null) {
                        support = new double[environment.getNrOfTargetCategories()];
                        for (int i = 0; i < support.length; i++) {
                            support[i] = ops.rnd.nextDouble();
                            totalSupport += support[i];
                        }
                    }
                    nrOfClasses = support.length;

                } else {
                    support = new double[1];
                }
                probs = null;
                if (ops.getPROBLEM_TYPE() != Options.CLASSIFICATION) {
                    value = calcRegValue(data);
                }
            }

            for (Prediction p : data.values()) {
                p.setLeaf(this);
                p.setSupport(support);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private double calcRegValue(PredictionContainer data) {
        double value = 0;
        for (Prediction p : data.values()) {
            value += p.getTargetValue() / data.values().size();
        }
        return value;
    }

    public void setValue(double value) {
        this.value = value;
    }

    public double getValue() {
        return value;
    }

    public void setProb(double prob) {
        this.prob = prob;
    }

    public double getProb() {
        return 0;//getProbs()[majority];
    }

    public Object clone() {
        ProbTargetPred2 newProbTargetPred2;
        try {
            newProbTargetPred2 = new ProbTargetPred2();
            newProbTargetPred2.setOptions(ops);
            newProbTargetPred2.setEnvironment(environment);
            newProbTargetPred2.setValue(new Double(value));
            newProbTargetPred2.setProb(new Double(prob));
            newProbTargetPred2.lowerProb = new Double(lowerProb);
            newProbTargetPred2.setCount(count);
            newProbTargetPred2.setParent(parent);
            newProbTargetPred2.support = support;
            newProbTargetPred2.majority = majority;
            newProbTargetPred2.totalSupport=totalSupport;
        } catch (grex.BNFException e) {
            ErrorManager.getInstance().reportError(e);
            return null;
        }
        return newProbTargetPred2;
    }

    /** @todo Om endast enn kategori finns kommer denna att volja lika ofta somma alla andra sammtidigt */
    public String toString() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(1);
        double[] pb = support;
        if (super.ops.getPROBLEM_TYPE() == Options.CLASSIFICATION) {
            String s = "[ ";
            for (int i = 0; i < pb.length; i++) {
                if (count > 0) {
                    s += nf.format((Double) pb[i] * 100 / totalSupport) + "% ";
                } else {
                    return "[Not Used]";
                }
            }
            return s + "]";
        } else {
            return "" + nf.format(value);
        }
    }

    public double[] getProbs() {
        if (probs == null) {
            probs = new double[support.length];
            for (int i = 0; i < support.length; i++) {
                probs[i] = (1.0 + support[i]) / (support.length + totalSupport);
            }
        }
        return probs;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public double getLowProb() {
        return lowerProb;
    }
}

